<template>
  <el-dialog
    title="设置定时策略"
    v-model="state.show"
    width="950px"
    :close-on-press-escape="false"
    :close-on-click-modal="false"
    append-to-body
    destroy-on-close
  >
    <el-form ref="formRef" :model="tableData" :rules="rules">
      <el-table :data="tableData" border style="width: 100%">
        <el-table-column prop="id" label="策略编号" width="90" align="center" />
        <el-table-column label="策略开关" width="140">
          <template #default="scope">
            <el-form-item :prop="'[' + scope.$index + '].timing_onoff'" :rules="rules.timing_onoff">
              <el-select 
                v-model="scope.row.timing_onoff" 
                placeholder="请选择"
                :disabled="isRowDisabled(scope.$index)"
                @change="handleSwitchChange(scope.row, scope.$index)"
              >
                <el-option label="关闭" value="0" />
                <el-option label="开启" value="1" />
              </el-select>
            </el-form-item>
          </template>
        </el-table-column>
        <el-table-column prop="timing_ctrl_type" label="灯控方式">
          <template #default="scope">
            <el-form-item :prop="'[' + scope.$index + '].timing_ctrl_type'" :rules="scope.row.timing_onoff === '1' ? rules.timing_ctrl_type : []">
              <el-select 
                v-model="scope.row.timing_ctrl_type" 
                placeholder="请选择"
                :disabled="isRowDisabled(scope.$index) || scope.row.timing_onoff === '0'"
              >
                <el-option label="开关控制" value="0" />
                <el-option label="调光控制" value="1" />
              </el-select>
            </el-form-item>
          </template>
        </el-table-column>
        <el-table-column prop="start_time" label="开始时间" width="160">
          <template #default="scope">
            <el-form-item :prop="'[' + scope.$index + '].start_time'" :rules="scope.row.timing_onoff === '1' ? rules.start_time : []">
              <el-time-picker 
                v-model="scope.row.start_time" 
                format="HH:mm"
                :disabled="isRowDisabled(scope.$index) || scope.row.timing_onoff === '0' || scope.$index > 0"
                :disabled-hours="() => disabledHours(scope.$index)"
                :disabled-minutes="(hour) => disabledMinutes(scope.$index, hour)"
                @change="handleStartTimeChange(scope.row, scope.$index)"
              />
            </el-form-item>
          </template>
        </el-table-column>
        <el-table-column prop="start_value" label="开始灯具设置值" width="160">
          <template #default="scope">
            <el-form-item :prop="'[' + scope.$index + '].start_value'" :rules="scope.row.timing_onoff === '1' ? rules.start_value : []">
              <el-select 
                v-if="scope.row.timing_ctrl_type == '0'" 
                v-model="scope.row.start_value" 
                placeholder="请选择"
                :disabled="isRowDisabled(scope.$index) || scope.row.timing_onoff === '0'"
              >
                <el-option label="开" value="1" />
                <el-option label="关" value="0" />
              </el-select>
              <el-input 
                v-else 
                v-model="scope.row.start_value" 
                @input="handleInput(scope.row)"
                placeholder="请输入"
                :disabled="isRowDisabled(scope.$index) || scope.row.timing_onoff === '0'"
              />
            </el-form-item>
          </template>
        </el-table-column>
        <el-table-column prop="end_time" label="结束时间" width="160">
          <template #default="scope">
            <el-form-item :prop="'[' + scope.$index + '].end_time'" :rules="scope.row.timing_onoff === '1' ? rules.end_time : []">
              <el-time-picker 
                v-model="scope.row.end_time" 
                format="HH:mm"
                :disabled="isRowDisabled(scope.$index) || scope.row.timing_onoff === '0' || isEndTimeDisabled(scope.$index)"
                :disabled-hours="() => disabledEndHours(scope.$index)"
                :disabled-minutes="(hour) => disabledEndMinutes(hour, scope.$index)"
                @change="handleEndTimeChange(scope.row, scope.$index)"
              />
            </el-form-item>
          </template>
        </el-table-column>
      </el-table>
    </el-form>
    <p style="color: red;margin-bottom: 0;">注：后一条的开始时间等于前一条的结束时间；所有开启策略的时间跨度不能超过24小时；当结束时间小于开始时间时，结束时间为第二天时间</p>
    <template #footer>
        <div class="dialog-footer">
          <el-button @click="cancel()">取消</el-button>
          <el-button type="primary" @click="submit">确认</el-button>
        </div>
      </template>
  </el-dialog>
</template>
<script lang="ts" setup>
import { serviceInvoke } from '../api/devices.api'
import { ElTimePicker, ElMessage, ElLoading } from 'element-plus'

const formRef = ref<any>(null)

// 定义行数据接口
interface RowData {
  id: string;
  timing_onoff: string;
  timing_ctrl_type: string;
  start_time: string | Date | null;
  start_value: string;
  end_time: string | Date | null;
}

// 表单验证规则
const rules = {
  timing_onoff: [
    { required: true, message: '请选择策略开关', trigger: 'change' }
  ],
  timing_ctrl_type: [
    { required: true, message: '请选择灯控方式', trigger: 'change' }
  ],
  start_time: [
    { required: true, message: '请选择开始时间', trigger: 'change' }
  ],
  start_value: [
    { required: true, message: '请填写开始灯具设置值', trigger: 'change' }
  ],
  end_time: [
    { required: true, message: '请选择结束时间', trigger: 'change' }
  ]
}

const state = reactive({
  show: false,
  row: {} as any,
})

// 初始化表格数据
const tableData = ref<RowData[]>([
  { id: '1', timing_onoff: '0', timing_ctrl_type: '', start_time: '', start_value: '', end_time: '' },
  { id: '2', timing_onoff: '0', timing_ctrl_type: '', start_time: '', start_value: '', end_time: '' },
  { id: '3', timing_onoff: '0', timing_ctrl_type: '', start_time: '', start_value: '', end_time: '' },
  { id: '4', timing_onoff: '0', timing_ctrl_type: '', start_time: '', start_value: '', end_time: '' },
  { id: '5', timing_onoff: '0', timing_ctrl_type: '', start_time: '', start_value: '', end_time: '' },
  { id: '6', timing_onoff: '0', timing_ctrl_type: '', start_time: '', start_value: '', end_time: '' }
])

// 将时间（字符串或Date）转换为小时数字
const getHourFromTime = (time: string | Date | null): number => {
  if (!time) return 0
  if (typeof time === 'string') {
    const parts = time.split(':')
    return parseInt(parts[0], 10) || 0
  }
  return time instanceof Date ? time.getHours() : 0
}

// 将时间（字符串或Date）转换为分钟数字
const getMinuteFromTime = (time: string | Date | null): number => {
  if (!time) return 0
  if (typeof time === 'string') {
    const parts = time.split(':')
    return parseInt(parts[1], 10) || 0
  }
  return time instanceof Date ? time.getMinutes() : 0
}

// 将时间（字符串或Date）转换为总分钟数
const getMinutesFromTime = (time: string | Date | null): number => {
  if (!time) return 0
  const hours = getHourFromTime(time)
  const minutes = getMinuteFromTime(time)
  return hours * 60 + minutes
}

// 创建数字范围
const makeRange = (start: number, end: number): number[] => {
  const result: number[] = []
  // 确保start和end是有效的数字，并且end >= start
  if (!isNaN(start) && !isNaN(end) && end >= start) {
    for (let i = start; i <= end; i++) {
      result.push(i)
    }
  }
  return result
}

// 获取结束时间禁用的小时
const disabledEndHours = (index: number): number[] => {
  // 获取当前行
  const currentRow = tableData.value[index];
  
  // 如果当前行没有开始时间或者不是开启状态
  if (!currentRow.start_time || currentRow.timing_onoff !== '1') {
    return []; // 无限制
  }
  
  // 如果是第一行，且后面没有开启的行，结束时间没有特殊限制
  if (index === 0) {
    // 检查是否有后续开启的行
    const nextEnabledRowIndex = tableData.value.findIndex((row, i) => i > index && row.timing_onoff === '1');
    if (nextEnabledRowIndex === -1) {
      return []; // 没有后续开启的行，无限制
    }
  }
  
  // 检查当前行是否是最后一个启用的行
  const enabledRows = tableData.value.filter(row => row.timing_onoff === '1');
  const isLastEnabledRow = enabledRows.length > 0 && enabledRows[enabledRows.length - 1].id === currentRow.id;

  // 如果不是最后一个启用的行，结束时间只能等于下一个启用行的开始时间
  if (!isLastEnabledRow) {
    // 找到下一个启用的行
    let nextEnabledRowIndex = -1;
    for (let i = index + 1; i < tableData.value.length; i++) {
      if (tableData.value[i].timing_onoff === '1') {
        nextEnabledRowIndex = i;
        break;
      }
    }
    
    // 如果找到了下一个启用的行，并且它有开始时间
    if (nextEnabledRowIndex !== -1) {
      const nextEnabledRow = tableData.value[nextEnabledRowIndex];
      if (nextEnabledRow.start_time) {
        // 获取下一行开始时间的小时
        const nextStartHour = getHourFromTime(nextEnabledRow.start_time);
        
        // 只允许选择与下一行开始时间相同的小时
        const disabledHours: number[] = [];
        for (let h = 0; h < 24; h++) {
          if (h !== nextStartHour) {
            disabledHours.push(h);
          }
        }
        return disabledHours;
      }
    }
  }
  
  // 对于最后一个启用的行或无法确定下一个启用行的情况，使用原逻辑
  if (enabledRows.length === 0 || !enabledRows[0] || !enabledRows[0].start_time) {
    return [];
  }
  
  const firstRow = enabledRows[0];
  
  // 获取当前行的开始时间和第一行的开始时间
  let currentStartHour = 0;
  let currentStartMinute = 0;
  let firstStartHour = 0;
  let firstStartMinute = 0;
  
  // 解析当前行开始时间
  if (typeof currentRow.start_time === 'string') {
    const parts = currentRow.start_time.split(':');
    currentStartHour = parseInt(parts[0]);
    currentStartMinute = parseInt(parts[1]);
  } else if (currentRow.start_time instanceof Date) {
    currentStartHour = currentRow.start_time.getHours();
    currentStartMinute = currentRow.start_time.getMinutes();
  }
  
  // 解析第一行开始时间
  if (typeof firstRow.start_time === 'string') {
    const parts = firstRow.start_time.split(':');
    firstStartHour = parseInt(parts[0]);
    firstStartMinute = parseInt(parts[1]);
  } else if (firstRow.start_time instanceof Date) {
    firstStartHour = firstRow.start_time.getHours();
    firstStartMinute = firstRow.start_time.getMinutes();
  }

  // 计算第一行开始时间的总分钟数
  const firstStartTotalMinutes = firstStartHour * 60 + firstStartMinute;
  
  // 计算当前行开始时间的总分钟数
  const currentStartTotalMinutes = currentStartHour * 60 + currentStartMinute;
  
  // 计算从第一行开始时间到当前行开始时间已经使用的分钟数
  let usedMinutes;
  // 检查是否是跨天的情况
  const isCrossingDay = currentStartTotalMinutes < firstStartTotalMinutes;
  
  if (!isCrossingDay) {
    // 非跨天情况
    usedMinutes = currentStartTotalMinutes - firstStartTotalMinutes;
  } else {
    // 跨天情况
    usedMinutes = (currentStartTotalMinutes + 24 * 60) - firstStartTotalMinutes;
  }
  
  // 计算剩余可用分钟数（24小时限制）
  const remainingMinutes = 24 * 60 - usedMinutes;
  
  // 计算可用的最大小时数
  const maxRemainingHours = Math.floor(remainingMinutes / 60);
  const hasRemainingMinutes = remainingMinutes % 60 > 0;
  
  // 检查是否跨越24小时边界
  const isWrappingAround = currentStartHour + maxRemainingHours >= 24;
  const calculatedMaxHour = (currentStartHour + maxRemainingHours) % 24;
  
  const disabledHours: number[] = [];
  
  // 根据时间关系确定禁用的小时
  if (isCrossingDay) {
    // 当前行开始时间小于第一行开始时间（跨天情况）
    // 允许的范围：大于等于当前行开始时间 且 小于等于第一行开始时间
    for (let h = 0; h < 24; h++) {
      // 一个小时可选的条件：
      // 1. 等于当前行开始小时（对于开始小时，将由分钟限制处理）
      // 2. 大于当前行开始小时且小于等于第一行开始小时，或者在最大可用小时范围内
      if (h === currentStartHour) {
        // 当前开始小时是可选的，由分钟限制来控制
        continue;
      } else if (h > currentStartHour && h <= firstStartHour) {
        // 大于当前开始小时且小于等于第一行开始小时
        continue;
      } else if (h > currentStartHour && h <= currentStartHour + maxRemainingHours) {
        // 大于当前开始小时且在最大可用小时范围内
        continue;
      }
      
      // 其他情况都禁用
      disabledHours.push(h);
    }
  } else {
    // 非跨天情况，如第二行开始时间19:39结束时间应该可选19:39-09:26
    // 如果当前开始时间加上最大可用小时数超过了24小时，就说明跨了一天
    
    for (let h = 0; h < 24; h++) {
      // 一个小时可选的条件：
      if (h === currentStartHour) {
        // 1. 等于当前行开始小时（对于开始小时，将由分钟限制处理）
        continue;
      } else if (h === firstStartHour) {
        // 2. 等于第一行开始小时（始终可选，由分钟限制具体处理）
        continue;
      } else if (isWrappingAround) {
        // 3. 如果跨越24小时边界:
        if (h > currentStartHour || h < firstStartHour) {
          // 大于当前开始小时或小于第一行开始小时的都可以选
          continue;
        }
      } else {
        // 4. 非跨天情况且不跨越边界:
        if (h > currentStartHour && h < calculatedMaxHour) {
          continue;
        }
      }
      
      // 其他情况都禁用
      disabledHours.push(h);
    }
  }
  
  return disabledHours;
};

// 获取结束时间禁用的分钟
const disabledEndMinutes = (hour: number, rowIndex: number) => {
  const currentRow = tableData.value[rowIndex];
  
  // 如果当前行没有启用策略或开始时间，不限制分钟选择
  if (currentRow.timing_onoff !== '1' || !currentRow.start_time) {
    return [];
  }
  
  // 获取所有启用的行
  const enabledRows = tableData.value.filter(row => row.timing_onoff === '1');
  
  // 判断当前行是否是最后一个启用的行
  const isLastEnabledRow = enabledRows.length > 0 && enabledRows[enabledRows.length - 1].id === currentRow.id;
  
  // 如果不是最后一个启用的行，结束时间只能等于下一个启用行的开始时间
  if (!isLastEnabledRow) {
    // 找到下一个启用的行
    let nextEnabledRowIndex = -1;
    for (let i = rowIndex + 1; i < tableData.value.length; i++) {
      if (tableData.value[i].timing_onoff === '1') {
        nextEnabledRowIndex = i;
        break;
      }
    }
    
    // 如果找到了下一个启用的行，并且它有开始时间
    if (nextEnabledRowIndex !== -1) {
      const nextEnabledRow = tableData.value[nextEnabledRowIndex];
      if (nextEnabledRow.start_time) {
        // 获取下一行开始时间的小时和分钟
        const nextStartHour = getHourFromTime(nextEnabledRow.start_time);
        const nextStartMinute = getMinuteFromTime(nextEnabledRow.start_time);
        
        // 如果选择的小时等于下一行开始时间的小时
        if (hour === nextStartHour) {
          // 只允许选择与下一行开始时间相同的分钟
          const disabledMinutes: number[] = [];
          for (let m = 0; m < 60; m++) {
            if (m !== nextStartMinute) {
              disabledMinutes.push(m);
            }
          }
          return disabledMinutes;
        }
        
        // 如果选择的小时不等于下一行开始时间的小时，禁用所有分钟
        // (这种情况应该不会发生，因为小时已经被限制了)
        return makeRange(0, 59);
      }
    }
  }
  
  // 对于最后一个启用的行或无法确定下一个启用行的情况
  if (enabledRows.length === 0 || !enabledRows[0] || !enabledRows[0].start_time) {
    return [];
  }
  
  const firstRow = enabledRows[0];
  
  const currentStartHour = getHourFromTime(currentRow.start_time);
  const currentStartMinute = getMinuteFromTime(currentRow.start_time);
  const firstStartHour = getHourFromTime(firstRow.start_time);
  const firstStartMinute = getMinuteFromTime(firstRow.start_time);
  
  // 计算当前行和第一行的总分钟数
  const currentTotalMinutes = currentStartHour * 60 + currentStartMinute;
  const firstTotalMinutes = firstStartHour * 60 + firstStartMinute;
  
  // 判断是否是跨天的情况
  const isCrossDayScenario = currentTotalMinutes < firstTotalMinutes;
  
  // 计算从当前行开始时间到第一行开始时间已经使用的分钟数
  let usedMinutes;
  if (isCrossDayScenario) {
    // 跨天情况: 当前行开始时间小于第一行开始时间
    usedMinutes = (24 * 60) - firstTotalMinutes + currentTotalMinutes;
  } else {
    // 非跨天情况
    usedMinutes = currentTotalMinutes - firstTotalMinutes;
  }
  
  // 计算剩余可用分钟数（24小时限制），允许选择到与第一行开始时间完全相同的时间点
  const remainingMinutes = 24 * 60;
  
  // 计算可用的最大小时数和最后一小时的剩余分钟
  const maxRemainingHours = Math.floor(remainingMinutes / 60);
  const remainingMinutesInLastHour = remainingMinutes % 60;
  
  // 计算结束时间的最大小时
  const maxEndHour = (currentStartHour + maxRemainingHours) % 24;
  
  let disabledMinutes: number[] = [];
  
  // 只对最后一个启用行进行特殊处理，确保不超过回到第一行的时间
  if (isLastEnabledRow) {
    // 当最后一行和第一行在同一小时，且选择的就是这个小时
    if (currentStartHour === firstStartHour && hour === currentStartHour) {
      // 在这种情况下，分钟必须大于当前行开始分钟且小于或等于第一行开始分钟
      for (let i = 0; i < 60; i++) {
        if (i <= currentStartMinute || i > firstStartMinute) { // 注意这里使用 > 而不是 >=
          disabledMinutes.push(i);
        }
      }
      return disabledMinutes;
    }
    
    // 选择的小时是第一行开始小时
    if (hour === firstStartHour) {
      // 禁用大于第一行开始分钟的分钟（允许等于）
      for (let i = firstStartMinute + 1; i < 60; i++) {
        disabledMinutes.push(i);
      }
    }
    
    // 如果选择的小时等于当前行开始小时，禁用小于等于开始分钟的分钟
    if (hour === currentStartHour) {
      for (let i = 0; i <= currentStartMinute; i++) {
        disabledMinutes.push(i);
      }
    }
    
    // 如果是最后可用小时，且不是当前开始小时
    if (hour === maxEndHour && maxEndHour !== currentStartHour) {
      // 在剩余可用时间内只能选择到特定分钟
      for (let i = remainingMinutesInLastHour; i < 60; i++) {
        disabledMinutes.push(i);
      }
    }
  }
  
  return disabledMinutes;
};

// 验证时间跨度是否在24小时以内
const validateTimesSpan = (): boolean => {
  // 找到所有开启的策略行
  const enabledRows = tableData.value.filter(row => row.timing_onoff === '1')
  
  // 如果没有开启的策略，返回true
  if (enabledRows.length === 0) {
    return true
  }
  
  // 提取第一个和最后一个开启的策略
  const firstEnabledRow = enabledRows[0]
  const lastEnabledRow = enabledRows[enabledRows.length - 1]
  
  // 如果没有足够的时间信息，返回true
  if (!firstEnabledRow.start_time || !lastEnabledRow.end_time) {
    return true
  }
  
  // 计算时间差（分钟）
  const startMinutes = getMinutesFromTime(firstEnabledRow.start_time)
  const endMinutes = getMinutesFromTime(lastEnabledRow.end_time)
  
  // 计算时间差，考虑是否跨天
  let minutesDiff
  
  // 检查是否是跨天的时间设置
  if (endMinutes < startMinutes) {
    minutesDiff = (24 * 60) - startMinutes + endMinutes
  } else {
    minutesDiff = endMinutes - startMinutes
  }
  
  // 如果时间跨度超过24小时，显示警告并返回false
  if (minutesDiff > 24 * 60) {
    ElMessage.warning('设置的时间跨度已超过24小时，请调整')
    return false
  }
  
  // 检查相邻行的时间连续性
  for (let i = 0; i < enabledRows.length - 1; i++) {
    const currentEndMinutes = getMinutesFromTime(enabledRows[i].end_time)
    const nextStartMinutes = getMinutesFromTime(enabledRows[i + 1].start_time)
    
    // 检查是否连续
    if (currentEndMinutes !== nextStartMinutes) {
      ElMessage.warning('相邻策略的结束时间和开始时间必须一致，请调整')
      return false
    }
  }
  
  return true
}

// 判断行是否应该被禁用
const isRowDisabled = (index: number) => {
  if (index === 0) return false; // 第一行永远可编辑
  
  // 检查前一行是否是启用状态，只有前一行启用了，当前行才能编辑
  const prevRow = tableData.value[index - 1];
  return prevRow.timing_onoff !== '1';
}

// 更新策略开关变化函数，增加对循环完成的检测
const handleSwitchChange = (row: any, index: number) => {
  if (row.timing_onoff === '0') {
    // 如果策略开关设为关闭，则将后面所有行的开关也设为关闭
    for (let i = index + 1; i < tableData.value.length; i++) {
      tableData.value[i].timing_onoff = '0'
    }
  } else {
    // 在开启当前行前，计算已启用行(不包括当前行)的时间总和
    const enabledRows = tableData.value.filter((r, i) => i !== index && r.timing_onoff === '1');
    
    // 找到第一个启用的行
    const firstEnabledRow = enabledRows.length > 0 ? enabledRows[0] : null;
    // 找到最后一个启用的行
    const lastEnabledRow = enabledRows.length > 0 ? enabledRows[enabledRows.length - 1] : null;
    
    if (firstEnabledRow && lastEnabledRow && firstEnabledRow.start_time && lastEnabledRow.end_time) {
      // 特殊情况：如果最后一行的结束时间与第一行的开始时间相同，说明已经完成了24小时循环
      const firstStartHour = getHourFromTime(firstEnabledRow.start_time);
      const firstStartMinute = getMinuteFromTime(firstEnabledRow.start_time);
      const lastEndHour = getHourFromTime(lastEnabledRow.end_time);
      const lastEndMinute = getMinuteFromTime(lastEnabledRow.end_time);
      
      if (firstStartHour === lastEndHour && firstStartMinute === lastEndMinute) {
        row.timing_onoff = '0';
        ElMessage.warning('已使用全部24小时时间，无法开启更多策略');
        return;
      }
      
      // 计算已用时间
      const startMinutes = getMinutesFromTime(firstEnabledRow.start_time);
      const endMinutes = getMinutesFromTime(lastEnabledRow.end_time);
      
      // 计算已用时间（分钟），考虑是否跨天
      let usedMinutes;
      if (endMinutes < startMinutes) {
        usedMinutes = (24 * 60) - startMinutes + endMinutes;
      } else {
        usedMinutes = endMinutes - startMinutes;
      }
      
      // 如果已用时间接近24小时
      if (usedMinutes >= 24 * 60 - 1) {
        row.timing_onoff = '0';
        ElMessage.warning('已使用全部24小时时间，无法开启更多策略');
        return;
      }
    }
    
    // 开启时，如果前面行有结束时间，当前行的开始时间设置为前一行的结束时间
    if (index > 0 && tableData.value[index-1].timing_onoff === '1' && tableData.value[index-1].end_time) {
      row.start_time = tableData.value[index-1].end_time;
    } else if (index === 0 && !row.start_time) {
      // 如果是第一行且没有开始时间，设置一个默认时间
      const now = new Date();
      now.setSeconds(0);
      now.setMilliseconds(0);
      row.start_time = now;
    }
    
    // 如果开启的是中间行，确保后续已开启的行的时间连续性
    if (index > 0 && index < tableData.value.length - 1) {
      // 查找下一个开启的行
      let nextEnabledIndex = -1;
      for (let i = index + 1; i < tableData.value.length; i++) {
        if (tableData.value[i].timing_onoff === '1') {
          nextEnabledIndex = i;
          break;
        }
      }
      
      // 如果找到了下一个开启的行，更新它的开始时间
      if (nextEnabledIndex !== -1 && row.end_time) {
        tableData.value[nextEnabledIndex].start_time = row.end_time;
      }
    }
  }
  
  // 更新视图
  tableData.value = [...tableData.value];
  
  // 更新时间连续性
  updateTimeConsistency();
  
  // 验证时间跨度
  validateTimesSpan();
}

// 判断结束时间是否应该被禁用
const isEndTimeDisabled = (index: number) => {
  // 所有行的结束时间都可以选择，但会有时间选择限制
  return false;
}

// 处理开始时间变化（仅对第一行有效）
const handleStartTimeChange = (row: any, index: number) => {
  // 如果是第一行，改变了开始时间但没有结束时间，可以设置一个默认的结束时间
  if (index === 0 && !row.end_time) {
    // 设置为开始时间后1小时
    if (row.start_time instanceof Date) {
      const endTime = new Date(row.start_time);
      endTime.setHours(endTime.getHours() + 1);
      row.end_time = endTime;
    } else if (typeof row.start_time === 'string') {
      const parts = row.start_time.split(':');
      if (parts.length === 2) {
        let hour = parseInt(parts[0]) + 1;
        if (hour >= 24) hour = hour % 24;
        row.end_time = `${hour.toString().padStart(2, '0')}:${parts[1]}`;
      }
    }
  }
  
  // 更新时间连续性
  updateTimeConsistency();
  
  // 验证时间跨度
  validateTimesSpan();
}

// 处理结束时间变化
const handleEndTimeChange = (row: any, index: number) => {
  // 如果下一行开关是打开的，需要同步当前行的结束时间到下一行的开始时间
  if (index < tableData.value.length - 1 && tableData.value[index+1].timing_onoff === '1') {
    tableData.value[index+1].start_time = row.end_time;
  }
  
  // 更新视图以确保同步正确显示
  tableData.value = [...tableData.value];
  
  // 更新时间连续性和验证时间跨度
  updateTimeConsistency();
  validateTimesSpan();
  
  // 检查是否已经用尽24小时，如果是，则禁用后续行
  checkAndDisableExcessRows();
}

// 更新时间连续性
const updateTimeConsistency = () => {
  // 只处理开启的行，确保它们之间的时间连续性
  let lastEnabledIndex = -1;
  
  for (let i = 0; i < tableData.value.length; i++) {
    const currentRow = tableData.value[i];
    
    // 如果当前行是开启状态
    if (currentRow.timing_onoff === '1') {
      // 如果之前有开启的行且当前行不是第一行
      if (lastEnabledIndex !== -1 && i > 0) {
        const lastRow = tableData.value[lastEnabledIndex];
        
        // 确保当前行的开始时间与上一个开启行的结束时间一致
        if (lastRow.end_time) {
          // 强制同步开始时间等于上一行的结束时间
          currentRow.start_time = lastRow.end_time;
          
          // 如果当前行没有结束时间但有开始时间，设置一个默认的结束时间
          if (!currentRow.end_time && currentRow.start_time) {
            if (currentRow.start_time instanceof Date) {
              const endTime = new Date(currentRow.start_time);
              endTime.setHours(endTime.getHours() + 1);
              currentRow.end_time = endTime;
            } else if (typeof currentRow.start_time === 'string') {
              const parts = currentRow.start_time.split(':');
              if (parts.length === 2) {
                let hour = parseInt(parts[0]) + 1;
                if (hour >= 24) hour = hour % 24;
                currentRow.end_time = `${hour.toString().padStart(2, '0')}:${parts[1]}`;
              }
            }
          }
        }
      } else if (i === 0) {
        // 如果是第一个启用的行，并且没有结束时间但有开始时间
        if (!currentRow.end_time && currentRow.start_time) {
          if (currentRow.start_time instanceof Date) {
            const endTime = new Date(currentRow.start_time);
            endTime.setHours(endTime.getHours() + 1);
            currentRow.end_time = endTime;
          } else if (typeof currentRow.start_time === 'string') {
            const parts = currentRow.start_time.split(':');
            if (parts.length === 2) {
              let hour = parseInt(parts[0]) + 1;
              if (hour >= 24) hour = hour % 24;
              currentRow.end_time = `${hour.toString().padStart(2, '0')}:${parts[1]}`;
            }
          }
        }
      }
      
      lastEnabledIndex = i;
    }
  }
};

// 获取禁用的小时
const disabledHours = (index: number) => {
  // 第一行没有限制
  if (index === 0) {
    return []
  }
  
  // 确保索引有效
  if (index <= 0 || index >= tableData.value.length) {
    return []
  }
  
  // 检查前一行是否启用和是否有结束时间
  const prevRow = tableData.value[index - 1]
  if (prevRow.timing_onoff !== '1' || !prevRow.end_time) {
    return []
  }
  
  // 解析前一行的结束时间（支持字符串或日期对象）
  let prevEndHour: number = 0
  
  if (typeof prevRow.end_time === 'string') {
    const timeParts = prevRow.end_time.split(':')
    prevEndHour = parseInt(timeParts[0])
  } else if (prevRow.end_time instanceof Date) {
    prevEndHour = prevRow.end_time.getHours()
  }
  
  // 允许的小时必须等于前一行的结束时间小时
  const allowedHours = [prevEndHour];
  const disabledHours: number[] = [];
  
  for (let h = 0; h < 24; h++) {
    if (!allowedHours.includes(h)) {
      disabledHours.push(h);
    }
  }
  
  return disabledHours;
}

// 获取禁用的分钟
const disabledMinutes = (index: number, selectedHour: number) => {
  // 第一行没有限制
  if (index === 0) {
    return []
  }
  
  // 确保索引有效
  if (index <= 0 || index >= tableData.value.length) {
    return []
  }
  
  // 检查前一行是否启用和是否有结束时间
  const prevRow = tableData.value[index - 1]
  if (prevRow.timing_onoff !== '1' || !prevRow.end_time) {
    return []
  }
  
  // 解析前一行的结束时间（支持字符串或日期对象）
  let prevEndHour: number = 0
  let prevEndMinute: number = 0
  
  if (typeof prevRow.end_time === 'string') {
    const timeParts = prevRow.end_time.split(':')
    prevEndHour = parseInt(timeParts[0])
    prevEndMinute = parseInt(timeParts[1])
  } else if (prevRow.end_time instanceof Date) {
    prevEndHour = prevRow.end_time.getHours()
    prevEndMinute = prevRow.end_time.getMinutes()
  }
  
  // 如果选择的小时等于前一行结束时间的小时，则只允许选择与前一行结束时间相同的分钟
  if (selectedHour === prevEndHour) {
    const allowedMinutes = [prevEndMinute];
    const disabledMinutes: number[] = [];
    
    for (let m = 0; m < 60; m++) {
      if (!allowedMinutes.includes(m)) {
        disabledMinutes.push(m);
      }
    }
    
    return disabledMinutes;
  }
  
  // 其他情况应该不会出现，因为小时已经被限制
  return makeRange(0, 59); // 全部禁用
}

const openDialog = (row: any) => {
  state.show = true
  state.row = row
  
  // 重置表格数据为默认值
  tableData.value = tableData.value.map(item => ({
    ...item,
    timing_onoff: '0',
    timing_ctrl_type: '',
    start_time: '',
    start_value: '',
    end_time: '',
  }))
  
  // 验证时间连续性和跨度
  updateTimeConsistency();
  validateTimesSpan();
}

const handleInput = (row) => {
  let value = Number(row.start_value)
  if (isNaN(value)) {
    row.start_value = ''
    return
  }
  if (value > 100) {
    row.start_value = '100'
  } else if (value <= 0) {
    row.start_value = '0'
  }
}

const cancel = () => {
  state.show = false 
}

const submit = () => {
  // 使用Element Plus自带的表单校验
  if (!formRef.value) return;
  
  formRef.value.validate(async (valid: boolean) => {
    if (!valid) {
      ElMessage.error('请填写完整的信息');
      return;
    }
    
    // 确保时间连续性
    updateTimeConsistency();
    
    // 验证时间跨度
    if (!validateTimesSpan()) {
      ElMessage.error('时间跨度超过24小时，请调整后再提交');
      return;
    }
    
    // 计数变量，用于跟踪成功调用的次数
    let successCount = 0;
    let totalRows = tableData.value.length; // 总行数为6行
    
    // 显示加载中
    const loading = ElLoading.service({
      lock: true,
      text: '提交中...',
      background: 'rgba(0, 0, 0, 0.7)',
    });
    
    try {
      // 为所有行调用接口，不管是否启用
      for (const row of tableData.value) {
        // 格式化时间数据为'HHMMSS'格式
        let startTime = '000000'; // 默认为'000000'
        let endTime = '000000';   // 默认为'000000'
        
        // 处理开始时间
        if (row.start_time) {
          if (typeof row.start_time === 'string') {
            const parts = row.start_time.split(':');
            if (parts.length === 2) {
              startTime = `${parts[0]}${parts[1]}00`; // HH:MM -> HHMMSS
            }
          } else if (row.start_time instanceof Date) {
            const hours = row.start_time.getHours().toString().padStart(2, '0');
            const minutes = row.start_time.getMinutes().toString().padStart(2, '0');
            startTime = `${hours}${minutes}00`; // HHMMSS
          }
        }
        
        // 处理结束时间
        if (row.end_time) {
          if (typeof row.end_time === 'string') {
            const parts = row.end_time.split(':');
            if (parts.length === 2) {
              endTime = `${parts[0]}${parts[1]}00`; // HH:MM -> HHMMSS
            }
          } else if (row.end_time instanceof Date) {
            const hours = row.end_time.getHours().toString().padStart(2, '0');
            const minutes = row.end_time.getMinutes().toString().padStart(2, '0');
            endTime = `${hours}${minutes}00`; // HHMMSS
          }
        }
        
        // 构建参数
        const param = {
          id: row.id,
          timing_ctrl_type: row.timing_ctrl_type || '',
          timing_onoff: row.timing_onoff || '0',
          start_time: startTime,
          end_time: endTime,
          start_value: (row.start_value || '').toString() // 确保有默认值并转为字符串
        };
        
        // 调用接口
        const res = await serviceInvoke({
          deviceId: state.row.deviceId,
          service: 'timing_setting',
          args: param,
        });
        
        if (res.code === 200) {
          successCount++;
        } else {
          ElMessage.error("调用服务失败：" + (res.message || "未知错误"));
        }
      }
      
      if (successCount === totalRows) {
        ElMessage.success('所有策略设置成功');
      } else {
        ElMessage.warning(`有${totalRows - successCount}个策略设置失败`);
      }
    } catch (error: unknown) {
      const errorMessage = error instanceof Error ? error.message : '未知错误';
      ElMessage.error('提交时发生错误：' + errorMessage);
    } finally {
      loading.close();
    }
  });
}

// 检查已使用的时间是否达到24小时，如果是则禁用后续行
const checkAndDisableExcessRows = () => {
  // 获取所有启用的行
  const enabledRows = tableData.value.filter(row => row.timing_onoff === '1');
  
  // 如果没有启用的行，直接返回
  if (enabledRows.length === 0) return;
  
  // 如果只有一行启用，则无需检查
  if (enabledRows.length === 1) return;
  
  // 获取第一行和最后一行的时间
  const firstRow = enabledRows[0];
  const lastRow = enabledRows[enabledRows.length - 1];
  
  // 如果没有完整的时间信息，直接返回
  if (!firstRow.start_time || !lastRow.end_time) return;
  
  // 计算第一行开始时间和最后一行结束时间的分钟数
  const startMinutes = getMinutesFromTime(firstRow.start_time);
  const endMinutes = getMinutesFromTime(lastRow.end_time);
  
  // 特殊情况：如果最后一行的结束时间与第一行的开始时间相同，说明已经完成了24小时循环
  const firstStartHour = getHourFromTime(firstRow.start_time);
  const firstStartMinute = getMinuteFromTime(firstRow.start_time);
  const lastEndHour = getHourFromTime(lastRow.end_time);
  const lastEndMinute = getMinuteFromTime(lastRow.end_time);
  
  if (firstStartHour === lastEndHour && firstStartMinute === lastEndMinute) {
    // 找到最后一个启用行的索引
    const lastEnabledIndex = tableData.value.findIndex(row => row.id === lastRow.id);
    
    // 禁用后续行
    for (let i = lastEnabledIndex + 1; i < tableData.value.length; i++) {
      tableData.value[i].timing_onoff = '0';
    }
    
    // 提示用户
    ElMessage.warning('已使用全部24小时时间，后续策略已自动关闭');
    return;
  }
  
  // 计算已用时间（分钟），考虑是否跨天
  let usedMinutes;
  if (endMinutes < startMinutes) {
    // 如果结束时间小于开始时间，表示跨天
    usedMinutes = (24 * 60) - startMinutes + endMinutes;
  } else {
    usedMinutes = endMinutes - startMinutes;
  }
  
  // 如果已使用的时间达到或接近24小时（允许1分钟误差），禁用后续行
  if (usedMinutes >= 24 * 60 - 1) {
    // 找到最后一个启用行的索引
    const lastEnabledIndex = tableData.value.findIndex(row => row.id === lastRow.id);
    
    // 禁用后续行
    for (let i = lastEnabledIndex + 1; i < tableData.value.length; i++) {
      tableData.value[i].timing_onoff = '0';
    }
    
    // 提示用户
    ElMessage.warning('已使用全部24小时时间，后续策略已自动关闭');
  }
}

defineExpose({
  openDialog,
})
</script>

<style lang="scss" scoped>
.dialog-footer {
  padding-top: 20px;
  text-align: right;
}
.el-form-item {
  margin-bottom: 0;
}
</style>